#coding:utf8
import json

from django.conf import settings
from urllib.parse import urlencode,parse_qs
from urllib.request import urlopen


class OauthQQ(object):
    """
    QQ授权工具类,对视图逻辑进行抽取
    """
    def __init__(self,client_id=None,redirect_uri=None,client_secret=None):

        self.client_id = client_id or settings.QQ_APP_ID
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URL
        self.client_secret = client_secret or settings.QQ_APP_KEY

    def get_oauth_url(self,state):
        # 生成auth_url
        # https://graph.qq.com/oauth2.0/authorize
        # 请求参数请包含如下内容：
        # response_type   必须      授权类型，此值固定为“code”。
        # client_id       必须      申请QQ登录成功后，分配给应用的appid。
        # redirect_uri    必须      成功授权后的回调地址，必须是注册appid时填写的主域名下的地址，建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
        # state           必须      client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
        # scope              可选      scope=get_user_info


        # 设置base_url,注意添加 ?
        base_url = 'https://graph.qq.com/oauth2.0/authorize?'
        # 组织参数
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': state,
            'scope': 'get_user_info',
        }

        # 对参数进行urlencode,然后拼接url
        auth_url = base_url + urlencode(params)
        return auth_url

    def get_access_token(self, code):
        # 返回token
        # PC网站：https://graph.qq.com/oauth2.0/token
        # GET
        # grant_type      必须      授权类型，在本步骤中，此值为“authorization_code”。
        # client_id       必须      申请QQ登录成功后，分配给网站的appid。
        # client_secret   必须      申请QQ登录成功后，分配给网站的appkey。
        # code            必须      上一步返回的authorization
        # redirect_uri    必须      与上面一步中传入的redirect_uri保持一致。

        # 准备url,注意添加?
        base_url = 'https://graph.qq.com/oauth2.0/token?'
        params = {
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri
        }

        # base_url+拼接参数('https://graph.qq.com/oauth2.0/token?')
        url = base_url + urlencode(params)

        # 发送请求,获取响应
        response = urlopen(url)

        # 读取数据
        data = response.read().decode()

        query_params = parse_qs(data)

        # 获取token,并进行判断
        access_token = query_params.get('access_token')
        # print(access_token)
        # ['5F5893DBC5339A54B26AFD0A1312276F']
        if access_token is None:
            raise Exception('获取token失败')

        return access_token[0]

    def get_openid(self,token):

        """
        返回openid
        PC网站：https://graph.qq.com/oauth2.0/me

        参数	是否必须	含义
        access_token	必须	在Step1中获取到的access token。

        """

        base_url = 'https://graph.qq.com/oauth2.0/me?'

        params = {
            'access_token':token
        }

        url = base_url + urlencode(params)


        # 自己区获取数据
        response = urlopen(url)
        #获取数据
        data = response.read().decode()

        # print(data)
        #'callback( {"client_id":"101474184","openid":"32A792C9563858A10ACED089784D9B9E"} );'
        # 我们对返回的数据进行截取
        try:
            dict = json.loads(data[10:-4])
        except Exception:
            raise Exception('数据获取失败')

        # print(dict)

        openid = dict.get('openid')

        if openid:
            return openid

        return None
